﻿package ygg.encoding.swf
{
	import flash.utils.ByteArray;
	import flash.utils.getQualifiedClassName;
	import flash.xml.XMLDocument;
	import j.sus2maj7.encoding.*;
	import ygg.encoding.swf.version.SwfVersion;
	import ygg.encoding.swf.tag.*;
	import ygg.encoding.swf.type.v0.*;
	import ygg.encoding.swf.type.v3.*;
	
	public class SwfCodecFactory extends AbstractCodecFactory
	{
		public function getStringCodec(version:uint):ICodec
		{
			var retVal:ICodec;
			
			switch (version)
			{
				case SwfVersion.V3:
					retVal = new StringTypeCodec();
					break;
				case SwfVersion.V0:
					//return new StringTypeCodec();
					break;
				default:
					throw new Error("Invalid Version");
					break;
			}
			
			return retVal;
		}
		public function getEncoder(value:*, version:uint):ICodec
		{
			trace('TYPE', getQualifiedClassName(value));
			
			var retVal:ICodec;
			
			//trace( describeType(value) );
			
			if ( value === undefined )
			{
				trace('undefined');
				return new UndefinedTypeCodec();
			}
			else if (value === null )
			{
				trace('null');
				return new NullTypeCodec();
			}
			else if (value is Boolean )
			{
				if (value)
				{
					trace('true');
					return new TrueTypeCodec();
				}
				else
				{
					trace('false');
					return new FalseTypeCodec();
				}
			}
			else if (value is Number )
			{
				trace('Number');
				
				if (value is int && value < 0x10000000 && value > -0x10000000 )
				{
					trace('int');
					return new IntegerTypeCodec();
				}
				else
				{
					trace('double');
					return new DoubleTypeCodec();
				}
				
			}
			else if (value is String )
			{
				trace('String');
				return new StringTypeCodec();
				
			}//*
			else if (value is Array )
			{
				trace('Array');
				
				return new ArrayTypeCodec();
			}
			
			else if (value is XML )
			{
				trace('XML');
				return new XmlTypeCodec();
				
			}
			else if (value is XMLDocument )
			{
				trace('XMLDocument');
				return new XmlDocTypeCodec();
				
			}
			else if (value is Date )
			{
				trace('Date');
				return new DateTypeCodec();
				
			}
			else if (value is ByteArray )
			{
				trace('ByteArray');
				return new ByteArrayTypeCodec();
			}
			else
			{
				trace('Object');
				//Object
				return new ObjectTypeCodec();
			}
			
			//if simple, write marker
			//if string
			
			//if complex
			
			return retVal;
		}
		public function getDecoder(marker:uint, version:uint):ICodec
		{
			var retVal:ICodec;
			
			if (version == SwfVersion.V3)
			{
				if (marker & 1)
				{
					switch (marker)
					{
						case Swf3Marker.TRUE :
							return new TrueTypeCodec();
							break;
						case Swf3Marker.ARRAY :
							return new ArrayTypeCodec();
							break;
						case Swf3Marker.NULL :
							return new NullTypeCodec();
							break;
						case Swf3Marker.DOUBLE :
							return new DoubleTypeCodec();
							break;
						case Swf3Marker.XML_ :
							return new XmlTypeCodec();
							break;
						case Swf3Marker.XML_DOC :
							return new XmlDocTypeCodec();
							break;
						default:
							throw new Error("Invalid Marker");
							break;
					}
				}
				else
				{
					switch (marker)
					{
						case Swf3Marker.INTEGER :
							return new IntegerTypeCodec();
							break;
						case Swf3Marker.STRING :
							return new StringTypeCodec();
							break;
						case Swf3Marker.FALSE :
							return new FalseTypeCodec();
							break;
						case Swf3Marker.OBJECT :
							return new ObjectTypeCodec();
							break;
						case Swf3Marker.DATE :
							return new DateTypeCodec();
							break;
						case Swf3Marker.BYTEARRAY :
							return new ByteArrayTypeCodec();
							break;
						case Swf3Marker.UNDEFINED :
							return new UndefinedTypeCodec();
							break;
						default:
							throw new Error("Invalid Marker");
							break;
					}
				}
			}
			
			return retVal;
		}
	}
}